﻿using System;
using System.Collections.Specialized;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using CoreLibrary;
using NUnit.Framework;

namespace Modules.Tracking.API {

    [TestFixture]
    public class EverFastAPI : IShipmentAPI {

        const string ObtainCookieUrl = "https://www.everfast.com.au/Plug/NoSearch.asp";
        const string TrackUrl = "https://www.everfast.com.au/Plug/NoSearch.asp?action=ss";

        public static readonly Regex TablePattern = new Regex(@"<table\s+id='t2'>(.|\r\n)*?</table>", RegexOptions.Compiled);

        [Test]
        public void TestTrack() {
            var result = Track("1234556789");
            Console.WriteLine(result);
        }

        public string Track(string trackingId) {
            Asserts.NotBlank(trackingId, "Tracking ID can not be empty.");

            var payload = CreatePayload(trackingId);
            var request = CreatePostRequest(TrackUrl, payload, ObtainCookie());
            var content = Encoding.UTF8.GetBytes(payload);
            using (var stream = request.GetRequestStream()) {
                stream.Write(content, 0, content.Length);
                stream.Flush();
                stream.Close();
                using (var response = (HttpWebResponse)request.GetResponse()) {
                    var binary = IOUtil.Read(response.GetResponseStream());
                    var html   = Encoding.UTF8.GetString(binary);
                    var match  = TablePattern.Match(html);
                    if (match.Success) {
                        return html.Substring(match.Index, match.Length);
                    }
                    throw new Exception("查询失败， EWE可能换了输出结果元素.");
                }
            }
        }

        private static CookieContainer ObtainCookie() {
            var request = (HttpWebRequest)WebRequest.Create(ObtainCookieUrl);
            request.Method = "GET";
            request.ReadWriteTimeout = 500000000;
            request.Timeout = 500000000;
            request.ProtocolVersion = HttpVersion.Version11;
            request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
            request.Host = "www.everfast.com.au";
            request.CookieContainer = new CookieContainer();
            using (request.GetResponse()) {
                return request.CookieContainer;
            }
        }

        private static HttpWebRequest CreatePostRequest(string url, string payload, CookieContainer cookies) {
            var request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = "POST";
            request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
            request.Referer = "https://www.everfast.com.au/Plug/NoSearch.asp";
            request.Host = "www.everfast.com.au";
            request.KeepAlive = true;
            request.CookieContainer = cookies;
            request.ContentLength = payload.Length;
            request.ContentType = "application/x-www-form-urlencoded";
            request.Headers.Add(new NameValueCollection {
                {"Accept-Encoding", "gzip, deflate"},
                {"Accept-Language", "en-US,en;q=0.5"},
            });
            return request;
        }

        private static string CreatePayload(string trackingId) {
            var collection = HttpUtility.ParseQueryString(string.Empty, Encoding.UTF8);
            collection.Add("cno", trackingId);
            collection.Add("w", "everfast");
            return collection.ToString();
        }

    }
}